package com.yzr.util;

import cn.hutool.core.io.FileUtil;
import com.google.common.collect.Lists;
import com.yzr.exception.ConversionException;
import lombok.extern.slf4j.Slf4j;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Path;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @description
 * @author: yzr
 * @date: 2021/10/29 14:52
 **/
@Slf4j
@Component
public class ConverterUtil {

    @Resource
    private DocumentConverter documentConverter;

    /**
     * html头
     */
    private final static String HEAD = "<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"></head><body>";
    /**
     * html尾
     */
    private final static String TAIL = "</pre></body></html>";


    /**
     * 转换
     *
     * @param source 源文件
     * @param target 目标文件
     * @return 目标文件
     */
    public File converterPdf(@Valid @NotBlank(message = "文件转换失败，源文件不存在") final String source,
                             final String target,
                             final DocumentFormat documentFormat) {

        // 校验源文件目录是否存在
        final File file = new File(target);

        // 校验源是否存在
        if (!file.exists() || !file.isFile()) {
            throw new ConversionException("文件转换失败,源文件不存在");
        }

        // 转换后的文件名
        final Path resultTarget = FileUtil.getParent(file, 1).toPath().resolve(
                FileOfType.newSuffix(file.getName(), documentFormat.getExtension()));

        // office转成pdf
        converterPdf(FileUtil.getInputStream(source),
                FileUtil.getOutputStream(resultTarget), DefaultDocumentFormatRegistry.PDF);

        return resultTarget.toFile();
    }

    /**
     * 转换
     *
     * @param source 源文件
     * @param target 目标文件
     * @return 目标文件
     */
    public InputStream converterPdf(@Valid @NotBlank(message = "文件转换失败，源文件不存在") final String source,
                                    final String target) {

        return FileUtil.getInputStream(converterPdf(source, target, DefaultDocumentFormatRegistry.PDF));
    }

    /**
     * 转换
     *
     * @param source 源文件
     * @param target 目标文件
     * @return 目标文件
     */
    public boolean converterPdf(final InputStream source, final OutputStream target) {

        return converterPdf(source, target, DefaultDocumentFormatRegistry.PDF);
    }

    /**
     * 转换
     *
     * @param source 源文件
     * @param target 目标文件
     * @return 目标文件
     */
    public boolean converterPdf(final InputStream source, final OutputStream target,
                                DocumentFormat documentFormat) {

        try {
            documentConverter.convert(source)
                    .to(target)
                    .as(documentFormat)
                    .execute();
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * text转换为html文件
     *
     * @param source 源
     * @param target 目标
     * @return 文件
     */
    public File converterHtml(final String source, final String target) {

        File file = FileUtil.file(source);
        if (!FileUtil.exist(file)) {
            return file;
        }

        //保存的位置
        CopyOnWriteArrayList<String> resultList = Lists.newCopyOnWriteArrayList();
        resultList.add(HEAD);
        resultList.addAll(FileUtil.readUtf8Lines(file));
        resultList.add(TAIL);

        return FileUtil.writeUtf8Lines(resultList, target);
    }

    /**
     * text转换为html文件
     *
     * @param source 源
     * @param target 目标
     * @return 文件
     */
    public boolean converterHtml(final InputStream source, OutputStream target) {
        if (source == null) {
            return false;
        }

        String readStr;
        final char[] chars = new char[1024];

        try (final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(target));
             final BufferedReader reader = new BufferedReader(new InputStreamReader(source))) {

            writer.write(HEAD);
            while ((readStr = reader.readLine()) != null) {
                writer.newLine();
                writer.write(readStr);
            }
            writer.write(TAIL);
        } catch (Exception e) {
            return false;
        }
        return true;
    }
}
